
import java.util.ArrayList;

/**
 * ControlRobot.java
 * Descripción: Se encarga de controlar al robot para recorrer el mapa y dirigirse
 * a un lugar específico.
 * @since 08/11/2012
 * @version 1.5
 * @author Diego García, Carnet 11360
 *         Oscar Castañeda, Carnet 11086 
 *         Luis Carlos Velásquez, Carnet 11085
 *         Sergio Argueta, Carnet 11029
 */
public class ControlRobot {
    
    //Robot al cual se está controlando.
    private Robot explorador;
    
    //Grafo en el cual se representa el área explorada por el robot.
    private Grafo grafo;
    
    //Lleva control de en que número de llamada a caminos() se va, para poder conocer cual 
    //es la primera llamada a dicho procedimiento.
    private int control;
    
    /**
     * Construye un nuevo controlador de Robot.
     * @param robot Robot que será controlado por esta instancia.
     */
    public ControlRobot(Robot robot){
        explorador = robot;
        //Se crea un grafo para un área cuadrada de 8 por lado.
        grafo = new Grafo(8);
        control = 0;
    }
    
    public void caminos(){
        control++;
        int ban=1;  //Si la bandera es múltiplo de 2, tiene camino derecho; 
                    //si es múltiplo de 3, tiene camino enfrente; si es múltiplo de 5 tiene camino izquierdo.
                    //si es 0, esta en un rincón.
        int filaInicio, colInicio, filaDestino, colDestino;
        if(control!=1){
            //Si no es la primera vez que se llama a caminos, es decir, no es el primer nodo que se busca,
            //se obtienen las coordenadas del punto de inicio.
            filaInicio = explorador.getFila();
            colInicio = explorador.getCol();
            System.out.println("Posicion de salida: Fila: "+filaInicio+", "+colInicio);
            //Se busca el siguiente nodo.
            ban = explorador.buscar_nodo();                                        
            //Y se guardan las coordenadas del punto final.
            filaDestino = explorador.getFila();
            colDestino = explorador.getCol();
            System.out.println("Posicion de llegada: Fila: "+filaDestino+", "+colDestino);
            //Se agrega una arista entre estos dos puntos.
            grafo.addEdge(filaInicio, colInicio, filaDestino, colDestino);
            System.out.println("Agregado al grafo");
        }else{
            //Si es la primera vez que se llama a caminos, iniciando la búsqueda.
            //Solo se ven los alrededores.
            ban = enviar.comunicacion(0)/100;             
            //Y se guarda la coordenada actual.
            filaInicio = explorador.getFila();
            colInicio = explorador.getCol();
            explorador.agregarPosicion(filaInicio, colInicio);
        }          
        //Se observa a donde se debería de ir ahora.
        if (ban!=1){
            if (ban%2==0){
                //Si se tiene libre a la derecha, se gira a la derecha y se busca el siguiente nodo.
                explorador.turn(1);
                caminos();
                System.out.println("Giro regreso derecha");
                explorador.turn(1);
            }
            if (ban%3==0){
                //Si se tiene libre enfrente, se busca el siguiente nodo.
                caminos();
                System.out.println("Giro regreso enfrente");
                explorador.turn(2);
            }
            if (ban%5==0){
                //Si se tiene libre a la izquierda, se gira en dicha dirección y se repite este procedimiento.
                explorador.turn(3);
                caminos();
                System.out.println("Giro regreso izquierda");
                explorador.turn(3);
            }               
        }
        //Al finalizar la búsqueda desde este nodo, el robot se voltea.
        if(control!=1){
            //Y si este proceso no corresponde al primero, control será mayor que uno y entonces
            //se regresará al nodo de donde se partió.
        	explorador.turn(2);
            explorador.regresar();
        }
        //Se disminuye control al salir de esta llamada de este procedimiento, asi al llegar a la primera, el valor será 1 de nuevo.
        control--;
    }
    
    /**
     * Devuelve el grafo que representa el área explorada por el robot.
     * @return Grafo con la información del área explorada.
     */
    public Grafo getGrafo(){
        return grafo;
    }

    /**
     * Da al robot las indicaciones para dirigirse a la coordenada indicada a partir
     * de su posición actual.
     * @param destino Coordenada de destino a la que se quiere ir.
     */
    public void dirigirseA(Coordenada destino) {
        Coordenada origen = new Coordenada(explorador.getFila(), explorador.getCol());
        //El proceso solo se realizará si el punto de origen es distino al de destino, ya que de lo contrario
        //no habría necesidad de moverse.
        if(!origen.equals(destino)){
            //Se obtiene la ruta más corta de la posición actual a la de destino.
            ArrayList<Integer> nodosRuta = grafo.getShortestPathRoute(origen, destino);
            for (int i = 0; i < nodosRuta.size()-1; i++){
                //Se toman los nodos en esa ruta de par en par
                Integer partida = nodosRuta.get(i);
                Integer llegada = nodosRuta.get(i+1);
                //Se gira al robot en la dirección que une a dichos nodos.
                explorador.girarEnDireccion(grafo.getDirectRouteDirection(partida, llegada));
                //Y se avanza hacia delante tantas veces como indica el grafo.
                explorador.regresar();
                //enviar.comunicacion(0);
                //for (int j = 0; j < grafo.getDirectRouteValue(partida, llegada); j++){
                //    explorador.moverAdelante();
                //}
            }
        }        
    }
    
}